<template>
    <div :style="{ height: '400px', width: '70vw' }">
      <div :id="toolbarId">
        <button type="button" class="ql-bold" />
        <button type="button" class="ql-italic" />
        <button type="button" class="ql-underline" />
        <button type="button" class="ql-strike" />
        <button type="button" class="ql-blockquote" />
        <!-- <button type="button" class="ql-list" :value="ordered" />
        <button type="button" class="ql-list" :value="bullet" /> -->
        <button type="button" class="ql-image" />
        <!-- <button type="button" class="ql-table" /> -->
        <button type="button" class="ql-link" />
        <select class="ql-color" />
        <button
          type="button"
          title='导入RTF'
          class="ql-import"
          style="outline: none"
          @click="handleImportRtf"
        >
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" class="feather feather-upload">
            <path d="M12 22L12 10M12 10L8 14M12 10L16 14" stroke="black" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
            <path d="M4 6H20" stroke="black" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
        </button>
        <button
          type="button"
          class="ql-export"
          style="outline: none"
          title='导出RTF'
          @click="handleExportRtf"
        >
          <svg style="transform: rotate(180deg);" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M12 22L12 10M12 10L8 14M12 10L16 14" stroke="black" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
            <path d="M4 6H20" stroke="black" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
          </svg>
        </button>
      </div>
      <div :style="{ height: '200px' }">
        <QuillEditor
          :modules="modules"
          :toolbar="modules.toolbar"
          :defaultValue="content"
          ref="richText"
          :style="{ height: '200px' }"
        />
      </div>
    </div>
  </template>
  
  <script setup>
  import { ref, onMounted } from 'vue';
  import { QuillEditor }  from '@vueup/vue-quill';
  import 'quill/dist/quill.snow.css';
  import BlotFormatter from 'quill-blot-formatter'
  import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html';
  import htmlToRtf from 'html-to-rtf';
  import { Document } from 'rtf.js/dist/RTFJS.bundle';
import { rtfArrayBufferToHtmlStr } from '../utils';
  
  
  const importRtfFileToString = async () => {
    return new Promise((resolve, reject) => {
        // let rtfTextContent = '';
        // 创建 input 元素
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = '.rtf';
        let isOpenFile = false;
        // 监听文件选择事件
        input.onchange = async (event) => {
            const file = event.target.files[0];
            if (file) {
                isOpenFile = true;
                // 读取文件内容
                const reader = new FileReader();
                reader.onload = (e) => {
                    const ab = e.target.result;
                    // 当文件读取完成后，调用 resolve 函数将结果传递出去
                    resolve({
                      name: file.name,
                      arrayBuffer: new Uint8Array(ab)
                    });
                };
                reader.onerror = (error) => {
                    // 如果文件读取出现错误，调用 reject 函数
                    reject(error);
                };
                reader.readAsArrayBuffer(file);
            }
        };
        // 取消事件
        window.addEventListener(
            'focus',
            () => {
                setTimeout(() => {
                    if (!isOpenFile) {
                        // 取消逻辑处理
                        reject(new Error('User cancelled file selection'));
                    }
                }, 300);
            },
            { once: true }
        );

        // 触发文件选择对话框
        input.click();
    });
};
  
  
  const convertRtfHtmlString = async (rtfString) => {
    try {
      const doc = new Document(stringToArrayBuffer(rtfString));
      const meta = doc.metadata();
      const html = await doc.render();
      const d = {};
      d.html = html;
      d.meta = meta;
      return d;
    } catch (e) {
      throw e;
    }
  };
  
  
  const stringToArrayBuffer = (string) => {
    const buffer = new ArrayBuffer(string.length);
    const bufferView = new Uint8Array(buffer);
    for (let i = 0; i < string.length; i++) {
      bufferView[i] = string.charCodeAt(i);
    }
    return buffer;
  };
  
  
  const content = ref('HELLO');
  const toolbarId = ref(`toolbar_${Math.random().toString(16).substring(2)}`);
  const richText = ref(null);
  
  
  const modules = {
    // modules: [],
    module: BlotFormatter,
    toolbar: {
      container: `#${toolbarId.value}`,
      handlers: {
        // insertStar: insertStar,
      },
    },
  };
  
  
  const handleImportRtf = async () => {
    try {
    const rtfContentStr = await importRtfFileToString();

    var decoder = new TextDecoder("utf-8");
      const d = await convertRtfHtmlString(decoder.decode(rtfContentStr.arrayBuffer));
      const htmlStr = d.html.map(div => div.outerHTML).join('\n');

    // const htmlStr = await rtfArrayBufferToHtmlStr(rtfContentStr.arrayBuffer);

      console.log({htmlStr});

    //   rtfArrayBufferToHtmlStr

      const editor = richText.value.getQuill();
      if (!editor) {
        return;
      }
      editor.setText('');
      editor.clipboard.dangerouslyPasteHTML(0, htmlStr);
    } catch (e) {
      console.error(e);
    }
  };
  
  
  const handleExportRtf = () => {
    const cfg = {};
    const editor = richText.value.getQuill();
    const deltaOps = editor.editor.delta.ops;
    const converter = new QuillDeltaToHtmlConverter(deltaOps, cfg);
    const html = converter.convert();
    // console.log(html);
    const rtfContent = htmlToRtf.convertHtmlToRtf(html);
    // from here on, works only on browser
    const blob = new Blob([rtfContent], { type: "application/rtf;charset=utf-8" });
    const blobURL = window.URL.createObjectURL(blob);
    const fileName = 'save.rtf';
    const tempLink = document.createElement('a');
    tempLink.style.display = 'none';
    tempLink.href = blobURL;
    const downloadName = decodeURIComponent(fileName);
    tempLink.setAttribute('download', downloadName);
    tempLink.download = downloadName;
    // alert(decodeURIComponent(fileName));
    // 兼容：某些浏览器不支持HTML5的download属性
    if (typeof tempLink.download === 'undefined') {
      tempLink.setAttribute('target', '_blank');
    }
    // 挂载a标签
    document.body.appendChild(tempLink);
    tempLink.click();
    setTimeout(() => {
      document.body.removeChild(tempLink);
      // 释放blob URL地址
      window.URL.revokeObjectURL(blobURL);
    }, 3000);
  };
  
  
  onMounted(() => {
    // 可以在这里添加一些需要在组件挂载后执行的操作
  });
  </script>
  
  
  <style scoped>
  /* 可以添加一些组件的样式 */
  </style>